package main

import (
	"errors"
	"fmt"
	"log"
	"time"

	uuid "github.com/satori/go.uuid"
	"inspur.com/cloudware/model"
	"inspur.com/cloudware/service/task"
)

// --------------------------------------一种task----------------------------------------------------------
//随意定义
type myTask struct {
	name  string
	times int
}

//实现一个execute方法
func (myTask *myTask) Execute() error {
	if myTask.times < 20 {
		myTask.times++
		fmt.Printf("*Execute* [%s], times = [%d]\n", myTask.name, myTask.times)
		return errors.New("fail")
	}
	return nil
}

//实现一个callback方法   这个方法会在任务执行完成后调用   result是否success取决于execute方法是否返回error
func (myTask *myTask) CallBack(result *task.Result) {
	if result.IsSuccessful() {
		fmt.Printf("*success* [%s]! times = [%d]\n", myTask.name, myTask.times)
	} else {
		fmt.Printf("*fail* [%s]! times = [%d]\n", myTask.name, myTask.times)
	}
}

// ---------------
// --------------------------------------另一种task----------------------------------------------------------
//随意定义
type yyTask struct {
	taskInfo task.TaskInfo
}

//实现一个execute方法
func (myTask *yyTask) Execute() error {
	//在这里干你想干的  此处用sleep 10s代替
	// taskinfo := myTask.taskInfo
	// taskRecord, _ := model.GetTask(taskinfo.ID)
	// fmt.Println(taskRecord)
	time.Sleep(5 * time.Second)
	myTask.UpdatePercentage(20)
	time.Sleep(5 * time.Second)
	myTask.UpdatePercentage(40)
	// taskRecord, _ = model.GetTask(taskinfo.ID)
	// fmt.Println(taskRecord)
	time.Sleep(5 * time.Second)
	myTask.UpdatePercentage(60)
	time.Sleep(5 * time.Second)
	myTask.UpdatePercentage(100)
	// taskRecord, _ = model.GetTask(taskinfo.ID)
	// fmt.Println(taskRecord)
	fmt.Printf("yao yao qie ke nao \n")

	return nil
}

//实现一个callback方法   这个方法会在任务执行完成后调用   result是否success取决于execute方法是否返回error
func (myTask *yyTask) CallBack(result *task.Result) {
	if result.IsSuccessful() {
		fmt.Printf("*success* ! comment = [%s]\n", myTask.taskInfo.Comment)
	} else {
		fmt.Printf("*failed* ! comment = [%s]\n", myTask.taskInfo.Comment)
	}
}

//实现一个GetTaskInfo方法
func (myTask *yyTask) GetTaskInfo() task.TaskInfo {
	return myTask.taskInfo
}

//实现一个GetTaskInfo方法
func (myTask *yyTask) UpdatePercentage(percent int64) error {
	taskinfo := myTask.taskInfo
	taskRecord, err := model.GetTask(taskinfo.ID)
	// fmt.Println(err)
	if err == nil {
		// fmt.Println("wuhawuha")
		// fmt.Println(percent)
		taskRecord.Percentage = percent
		taskRecord.UpdateTask()
		return nil
	} else {
		return err
	}

}

//实现一个cancel的方法  不能实现的直接return nil
//具体的cancel可能是kill -9  也可能只是修改一下数据库   也可能是往某个channel里发消息
//并不是所有task都需要支持cancel，比如reboot
func (myTask *yyTask) Cancel() error {
	return nil
}

// ------------以上为task示例---以下为具体执行--------------------------------------------------------------------------------------------
func main() {
	model.Database("test.db")
	// c := task.GetDefaultConfig()
	// taskPool, err := task.NewTaskPool(c)
	taskPool, err := task.GetTaskPool()
	if err != nil {
		log.Fatal(err)
	}
	taskPool.Start()
	defer taskPool.SafeClose()

	// for i := 0; i < 1; i++ {
	// 	t := &myTask{
	// 		name:  fmt.Sprintf("task - %d", i),
	// 		times: 0,
	// 	}
	// 	taskPool.PushTask(t)
	// }
	t := &yyTask{
		taskInfo: task.TaskInfo{
			ID:   uuid.NewV4().String(),
			Name: "yytest",
			// Comment: "just for fun",
			Type: "icm deploy",
		},
	}
	taskPool.PushTask(t)
	// tasks := taskPool.GetTaskAll()
	// for i := 0; i < len(tasks); i++ {
	// 	t := tasks[i]
	// 	fmt.Printf("slice[%v]=%v \n", i, t.TaskName)
	// 	fmt.Printf("slice[%v]=%v \n", i, t.Percentage)

	// }
	totalcount, tasks := taskPool.GetTaskByPage(1, 2)
	fmt.Printf("totalcount=%v \n", totalcount)
	for i := 0; i < len(tasks); i++ {
		t := tasks[i]
		fmt.Printf("slice[%v]=%v \n", i, t.TaskName)
		fmt.Printf("slice[%v]=%v \n", i, t.TaskComment)
		taskPool.DeleteTask(t.ID)
	}

	//等待一段时间  10秒之后开始执行safeclose方法，safeclose还会再等待任务执行完,但是不再retry
	//所以总时长可能大于10秒
	fmt.Printf("main sleep start %s \n", time.Now().String())
	time.Sleep(5 * time.Second)
	fmt.Printf("main sleep finish %s \n", time.Now().String())
}
